package com.chenyue.cm.auth.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author libingxing
 */
public class JWTHelper {

    private static final String BASE_64_SECURITY = "sKyBtl7GGSd6NasmH0sYeHPyAx4MkfgXsrRa7Ltqd2daKuCNFjGxmYgE10pYy4Ll";

    /**
     * 创建token
     *
     * @return
     * @throws Exception
     */
    public static String createToken(LoginUserInfo userInfo) throws Exception {

        // 签发时间
        Date iatDate = new Date();

        Map<String, Object> map = new HashMap<>(2);
        map.put("alg", "HS256");
        map.put("typ", "JWT");

        return JWT.create().withHeader(map).withIssuedAt(iatDate)
                .withClaim("userName", userInfo.getUserName()).withClaim("loginCode", userInfo.getLoginCode())
                .withClaim("loginTime", userInfo.getLoginTime()).withClaim("userId", userInfo.getUserId())
                .withClaim("userType", userInfo.getUserType()).withClaim("loginAddr", userInfo.getLoginAddr())
                .withClaim("token", userInfo.getToken()).sign(Algorithm.HMAC256(BASE_64_SECURITY));
    }

    /**
     * 解密Token
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static Map<String, Claim> verifyToken(String token) throws Exception {
        if (StringUtils.isBlank(token)) {
            throw new Exception("登录信息有误，请重新登录");
        }
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(BASE_64_SECURITY)).build();
        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        } catch (JWTVerificationException e) {
            e.printStackTrace();
            throw new Exception("登录信息过期，请重新登录");
        }
        return jwt.getClaims();
    }

    /**
     * 返回LoginUserInfo信息
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static LoginUserInfo verifyTokenReturnLoginUserInfo(String token) throws Exception {
        Map<String, Claim> claims = JWTHelper.verifyToken(token);
        LoginUserInfo userInfo = new LoginUserInfo();
        Field[] fields = userInfo.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (claims.containsKey(field.getName())) {
                Claim claim = claims.get(field.getName());
                field.setAccessible(true);
                Type type = field.getType();
                if (type == String.class) {
                    field.set(userInfo, claim.asString());
                } else if (type == Date.class) {
                    field.set(userInfo, claim.asDate());
                } else if (type == String[].class) {
                    field.set(userInfo, claim.asArray(String.class));
                } else if (type == Integer.class) {
                    field.set(userInfo, claim.asInt());
                }
            }
        }
        return userInfo;
    }

    public static void main(String[] args) throws Exception {
		LoginUserInfo userInfo = verifyTokenReturnLoginUserInfo("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyVHlwZSI6IiIsImV4cCI6MTU3NDQ5MDExNSwidXNlck5hbWUiOiLigo3hkKLigKLijITigKLhkKLigo4iLCJpYXQiOjE1NzQ0MDM3MTUsInVzZXJJZCI6NDh9.vIwZziNthvphtp_S5n2lhp4hNxBqVb2MQW7QyMeM3sM");
        System.err.println(userInfo.getUserId());
    }
}
